/** 
 * @ClassName:     GenerateMsgSendTaskNew.java 
 * @Description:   TODO(用一句话描述该文件做什么)  
 * @author         wangzhe  
 * @Date           2019年7月24日 下午5:30:35  
 */  


package com.huitone.smspfm.oldclient.asclient.send;

import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.aspectj.lang.reflect.CatchClauseSignature;
import org.springframework.beans.factory.annotation.Autowired;

import com.bin.common.utils.DateTimeUtils;
import com.bin.common.utils.StringUtils;
import com.huitone.smspfm.oldclient.app.AppStaticConfigs;
import com.huitone.smspfm.oldclient.asclient.SeqRepeatFilterQueue;
import com.huitone.smspfm.oldclient.asclient.SeqSmsFilterQueue;
import com.huitone.smspfm.oldclient.dao.SmsSendDao;
import com.huitone.smspfm.oldclient.dao.entity.SmsSend;
import com.huitone.smspfm.oldclient.logger.ExtLogger;
import com.huitone.smspfm.oldclient.model.MtGroup;
import com.huitone.smspfm.oldclient.model.MtSms;
import com.huitone.smspfm.oldclient.store.MtGroupTmpStore;
import com.huitone.smspfm.oldclient.store.MtTmpStore;
import com.huitone.smspfm.socket.client.SmsClient;
import com.huitone.smspfm.socket.protocol.sgip.constant.CommandID;
import com.huitone.smspfm.socket.protocol.sgip.constant.Constant;
import com.huitone.smspfm.socket.protocol.sgip.message.Message;
import com.huitone.smspfm.socket.protocol.sgip.message.msgbody.Submit2;
import com.huitone.smspfm.socket.protocol.sgip.message.msghead.Head;
import com.huitone.smspfm.socket.utils.SerialUtils;


public class GenerateMsgSendTaskNew extends Thread {
	
	private final static ExtLogger logger = ExtLogger.create(GenerateMsgSendTaskNew.class);
	
	private SmsClient client = null;
	
	//private boolean connectable = true;
	
	private boolean keepGoing = true;
	
//	private SeqRepeatFilterQueue filterQueue = new SeqRepeatFilterQueue();
	private SeqSmsFilterQueue filterQueue = SeqSmsFilterQueue.filterQueue;
	
	public GenerateMsgSendTaskNew(SmsClient client) {
		this.client = client;
	}
	
	private ExecutorService fixedThreadPool1 = new ThreadPoolExecutor(AppStaticConfigs.msgSendPoolSize, 
			AppStaticConfigs.msgSendPoolSize, 1L, TimeUnit.MINUTES, new ArrayBlockingQueue<>(AppStaticConfigs.msgSendPoolSize), new RejectedExecutionHandler() {
		
		@Override
		public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
			if (!executor.isShutdown()) {
				try {
					executor.getQueue().put(r);
				} catch (InterruptedException e) {
					logger.error(getClass().getSimpleName()+"fixedThreadPool1　 进程异常");
					e.printStackTrace();
				}
			}
		}
	});
	
	private ExecutorService fixedThreadPool2 = new ThreadPoolExecutor(AppStaticConfigs.msgSendPoolSize * 2, 
			AppStaticConfigs.msgSendPoolSize * 2, 1L, TimeUnit.MINUTES, new ArrayBlockingQueue<>(AppStaticConfigs.msgSendPoolSize * 2), new RejectedExecutionHandler() {
		
		@Override
		public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
			if (!executor.isShutdown()) {
				try {
					executor.getQueue().put(r);
				} catch (InterruptedException e) {
					logger.error(getClass().getSimpleName()+"fixedThreadPool2　 进程异常");
					e.printStackTrace();
				}
			}
		}
	});
	
	private boolean toSleep = false;
	
	private long sleepTime = 1000;
	
	@Override
	public void run() {
		
		logger.info("启动旧平台短信发送线程。");
		
		while (isKeepGoing() && !this.isInterrupted()) {

			if (client.testConnectableNow(false)) {

				fixedThreadPool1.execute(new Runnable() {

					@Override
					public void run() {

						try {
							MtDbReader dbReader = new MtDbReader();
							List<SmsSend> smsSends = dbReader.getSmsSend();

							if (smsSends !=null && !smsSends.isEmpty()) {
								Map<String, MtGroup> map = MtSms.parse(smsSends);

								if (!map.isEmpty()) {

									Iterator<Entry<String, MtGroup>> iterator = map
											.entrySet().iterator();

									while (iterator.hasNext()) {

										MtGroup mtGroup = iterator.next()
												.getValue();

										if (mtGroup.sendAble()) {
											// 如果短信当前是可发送的则进行发送(注:一般不可发送是因为长短信剩余分段没有读取到,可能的原因是长短信分段跨文件了)

											MtSms mtSms = mtGroup.merged();
											// 检查旧短信序号是否重复

											try {
												
												String oldSerialnoss = mtSms
														.getOldserialnos();
												// TODO
												boolean isRepeat = false; // 是否序号重复

												if (AppStaticConfigs.repeatseqsFilterOn) {
													List<String> serial = StringUtils
															.splitToList(
																	oldSerialnoss,
																	",");
													if (!StringUtils
															.isEmpty(serial)
															&& serial.size() > 0) {
														for (int i = 0; i < serial
																.size(); i++) {
															if (filterQueue
																	.contains(serial
																			.get(i))) {
																isRepeat = true;
																break;
															}
														}
													}
												}

												if (!isRepeat) {

													String serviceCode = AppStaticConfigs.serviceCode;
													if (AppStaticConfigs.isUseOldServiceCode) {
														serviceCode = mtSms
																.getServiceCode();
													}

													Submit2 submit = Submit2.build(
															mtSms.getMobileno(),
															AppStaticConfigs.srvNode,
															serviceCode,
															mtSms.getSendport(),
															1,
															Constant.MessageCodingE.GBK
																	.getValue(),
															Constant.MessageTypeE.SMS
																	.getValue(),
															mtSms.getContent(),
															mtSms.getClientname(),
															mtSms.getOldserialnos());
													Head head = Head.build(
															submit.length(),
															CommandID.SGIP_SUBMIT2,
															AppStaticConfigs.codeRule,
															StringUtils
																	.toIntegerP(DateTimeUtils
																			.dateToStr(
																					new Date(),
																					"MMddHHmmss")),
															SerialUtils
																	.getSerial());

													String serialNo = head
															.getSerialNo();

													mtSms.setSerialno(serialNo);
													mtSms.setSrvNode(AppStaticConfigs.srvNode);
													mtSms.setServiceCode(serviceCode);
													mtSms.setReportflag(1);
													mtSms.setCoderule(head
															.getSerialNoPart1());
													mtSms.setDatetime(head
															.getSerialNoPart2());
													mtSms.setSeqnumber(head
															.getSerialNoPart3());
													mtSms.setiSendTimes(1);
													mtSms.setLastSendTime(new Date());

													MtTmpStore.put(serialNo,
															mtSms);

													boolean status = client
															.sendMsg(head,
																	submit);

													if (!status)
														client.testConnectableNow(true);

													logger.submit(new Message(
															head, submit)
															.toString()
															+ ", 状态:"
															+ (status == true ? "提交成功"
																	: "提交失败"));
												} else {
													logger.error("短信因序列号重复被过滤掉: "
															+ mtSms.toString());
												}
											} catch (Exception e) {
												
												String msg = "mtSms is null and serialno is: "+mtGroup.getGroupKey();
												if(mtSms != null){
													msg = mtSms.toString();
												}
												logger.error("短信发送时发生错误: msg :"	+ msg, e.getMessage());
											}

										} else {
											// 长短信分段没有读齐,放入临时存储队列等待长短信分段读取完整
											fixedThreadPool2
													.execute(new Runnable() {

														@Override
														public void run() {
															MtGroupTmpStore
																	.add(mtGroup);
														}
													});
										}
									}
									toSleep = false;
								} else {
									toSleep = true;
								}

								if (AppStaticConfigs.backupSmsFiles) {
									dbReader.setBackupFile(true);
								}

								boolean backupFlag = dbReader.backupSms(smsSends);
								if (!backupFlag) {
									logger.error("备份发送短信失败！");
								}

							}
						} catch (Exception e) {
							e.printStackTrace();
							logger.error(" thread exception :" + e.getMessage());
						}
					}

				});
			} else {
				logger.warn("[短信发送任务]目标地址:" + client.getServerIp() + ":"
						+ client.getServerPort() + "不通!");
				toSleep = true;
			}

			try {
				if (toSleep) {
					Thread.sleep(sleepTime);
				}
			} catch (InterruptedException e) {
			}
		}
		
		if (fixedThreadPool1 != null && !fixedThreadPool1.isShutdown()) {
			fixedThreadPool1.shutdown();
		}
		
		if (fixedThreadPool2 != null && !fixedThreadPool2.isShutdown()) {
			fixedThreadPool2.shutdown();
		}
		
		logger.info("旧平台短信发送线程退出。");
	}

	public SmsClient getClient() {
		return client;
	}

	@Override
	public void destroy() {
		this.setKeepGoing(false);
	}

	public boolean isKeepGoing() {
		return keepGoing;
	}

	public void setKeepGoing(boolean keepGoing) {
		this.keepGoing = keepGoing;
	}
}
